#include "Spi.h"
#include "../../../bit/bit.h"

void Spi::init()
{
	//DDRB = (1<<5)|(1<<7)|(0<<6)|(1<<4);
	//SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
	unsigned char MOSI_PIN = 5;
	unsigned char MISO_PIN = 6;
	unsigned char SCK_PIN = 7;
	unsigned char SS_PIN = 4;
	if(GetBit(SPCR, 4)==1)
	{
		DDRB = SetBit(DDRB, MISO_PIN, 0);
		DDRB = SetBit(DDRB, MOSI_PIN, 1);
		DDRB = SetBit(DDRB, SCK_PIN, 1);
		DDRB = SetBit(DDRB, SS_PIN, 1);
	}
	else
	{
		DDRB = SetBit(DDRB, MISO_PIN, 1);
		DDRB = SetBit(DDRB, MOSI_PIN, 0);
		DDRB = SetBit(DDRB, SCK_PIN, 1);
		DDRB = SetBit(DDRB, SS_PIN, 0);
	}


}
void Spi::setMaster()
{
	SPCR = SetBit(SPCR, MSTR, 1); //set bit 4 to 1 for master.
}
void Spi::setSlave()
{
	SPCR = SetBit(SPCR, MSTR, 0); //set bit 4 to 0 for slave.
}
void Spi::setPolarityPhase(unsigned char pol, unsigned char phase)
{
	SPCR = SetBit(SPCR, CPOL, pol); 
	SPCR = SetBit(SPCR, CPHA, phase);
}
void Spi::setSPI_Interrupt(unsigned char s)
{
	SPCR = SetBit(SPCR, SPIE, s);
	//enable global interrupts
	SREG = SetBit(SREG, 7, 1);
}
void Spi::setSPI_transmissionFlag(unsigned char flag)
{
	SPSR = SetBit(SPSR, SPIF, flag);
}

void Spi::setDataOrder(unsigned char flag)
{
	SPCR = SetBit(SPCR, DORD, flag);
}
void Spi::setEnable(unsigned char flag)
{
	SPCR = SetBit(SPCR, SPE, flag);
}


//enum SPI_Prescaler { SPI_4, SPI_16, SPI_64, SPI_128, SPI_2, SPI_8, SPI_32, SPI_64_2};

void Spi::setPrescaler(unsigned char prescaler)
{
	unsigned char SPI2X_PIN = 0;
	unsigned char SPR1_PIN = 1;
	unsigned char SPR0_PIN = 0;
	switch(prescaler)
	{
		case SPI_4:
			SPSR = SetBit(SPSR, SPI2X_PIN, 0);
			SPCR = SetBit(SPCR, SPR1_PIN, 0);
			SPCR = SetBit(SPCR, SPR0_PIN, 0);
			break;
		case SPI_16:
			SPSR = SetBit(SPSR, SPI2X_PIN, 0);
			SPCR = SetBit(SPCR, SPR1_PIN, 0);
			SPCR = SetBit(SPCR, SPR0_PIN, 1);
			break;
		case SPI_64:
			SPSR = SetBit(SPSR, SPI2X_PIN, 0);
			SPCR = SetBit(SPCR, SPR1_PIN, 1);
			SPCR = SetBit(SPCR, SPR0_PIN, 0);
			break;
		case SPI_128:
			SPSR = SetBit(SPSR, SPI2X_PIN, 0);
			SPCR = SetBit(SPCR, SPR1_PIN, 1);
			SPCR = SetBit(SPCR, SPR0_PIN, 1);
			break;
		case SPI_2:
			SPSR = SetBit(SPSR, SPI2X_PIN, 1);
			SPCR = SetBit(SPCR, SPR1_PIN, 0);
			SPCR = SetBit(SPCR, SPR0_PIN, 0);
			break;
		case SPI_8:
			SPSR = SetBit(SPSR, SPI2X_PIN, 1);
			SPCR = SetBit(SPCR, SPR1_PIN, 0);
			SPCR = SetBit(SPCR, SPR0_PIN, 1);			
			break;
		case SPI_32:
			SPSR = SetBit(SPSR, SPI2X_PIN, 1);
			SPCR = SetBit(SPCR, SPR1_PIN, 1);
			SPCR = SetBit(SPCR, SPR0_PIN, 0);
			break;
		case SPI_64_2:
			SPSR = SetBit(SPSR, SPI2X_PIN, 1);
			SPCR = SetBit(SPCR, SPR1_PIN, 1);
			SPCR = SetBit(SPCR, SPR0_PIN, 1);
			break;
		default:
			SPSR = SetBit(SPSR, SPI2X_PIN, 0);
			SPCR = SetBit(SPCR, SPR1_PIN, 0);
			SPCR = SetBit(SPCR, SPR0_PIN, 0);
			break;
		
	}
}

void Spi::getSPI_ReceivedData(unsigned char* value)
{

	*value = SPDR; //value.

}

void Spi::setData(unsigned char send)
{
	//now worries about write collisions should be done as a pair.
	SPDR = send;
}

//performs the spi interrupt.
volatile unsigned char spiSentData=0;
volatile unsigned char spiReceivedData=0;
volatile unsigned char spiFlag=0;

void Spi::performSPI_Interrupt()
{
	unsigned char temp1;
	unsigned char temp2;
	temp1 = spiReceivedData;
	temp2 = spiSentData;
	getSPI_ReceivedData(&temp1);
	spiReceivedData = temp1;
	//setDataSPI(temp2);
	spiFlag = 1;
}

//perform interrupt service routine 
ISR(SPI_STC_vect)
{
	performSPI_Interrupt();
}




